package com.apache.common.plugins;

import com.apache.api.vo.ParamsVo;
import com.apache.cache.service.impl.LoadCacheFactory;
import com.apache.cache.service.impl.redis.ConfigUtil;
import com.apache.cache.service.impl.redis.RedisCoreFactory;
import com.apache.cache.util.Validator;
import com.apache.client.StringUtil;
import com.apache.database.datasource.DynamicDataSource;
import com.apache.ius.IusSqlTools;
import com.apache.ius.able.ScheduledExecutor;
import com.apache.ius.plugin.CustomMethodPlugin;
import com.apache.ius.plugin.IusPluginUtil;
import com.apache.tools.StrUtil;
import com.apache.uct.common.ToolsUtil;
import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description 通用缓存处理插件
 * @Date 2021/01/25 22:57
 */
public class PublicCachePluginImpl implements CustomMethodPlugin {
    protected Logger log = Logger.getLogger(getClass());
    @Override
    public Object beforeInvoke(Map<String, Object> map) {
        String modelTypes = String.valueOf(map.get("modelTypes"));
        if(modelTypes.startsWith("s_")){
            String tableObjName =modelTypes.substring(2);
            String sysName = StrUtil.doNull(String.valueOf(map.get("datasource")), DynamicDataSource.getInstance().getDefaultDataSourceKey());
            String cache_spaceName = sysName+"_"+tableObjName+"_cache";
            String cacheKey = StrUtil.doNull(String.valueOf(map.get("cacheKey")),"");
            Object obj = null;
            if(StrUtil.isNull(cacheKey)) {
                Jedis jedis = null;
                try{
                    jedis = RedisCoreFactory.getInstance().getJedis();
                    Map<byte[],byte[]> maps = jedis.hgetAll(cache_spaceName.getBytes());
                    if(maps != null && !maps.isEmpty()) {
                        List<Object> objs = new ArrayList();
                        for (Map.Entry<byte[], byte[]> entry : maps.entrySet()) {
                            if (null != entry.getValue()) {
                                Object objInfo = ConfigUtil.getInstance().ObjectToObject(ConfigUtil.getInstance().unserialize(entry.getValue()));
                                objs.add(objInfo);
                            }
                        }
                        obj = objs;
                    }
                } catch(Exception e) {
                } finally {
                    if(jedis != null){
                        jedis.close();
                    }
                }
            } else {
                obj = LoadCacheFactory.getInstance().getCacheManager(cache_spaceName).getCacheObjectByKey(cacheKey);
            }
            if(obj != null){
                map.put(CustomMethodPlugin.resultMark, "操作成功");
                map.put(CustomMethodPlugin.pluginInnerReturn, obj);
            }
        }
        return null;
    }

    @Override
    public Object doInvoke(Map<String, Object> map) {
        return null;
    }

    @Override
    public Object afterInvoke(Map<String, Object> map) {
        String modelTypes = String.valueOf(map.get("modelTypes"));
        String tableObjName =modelTypes.substring(2);
        String attr = ToolsUtil.getInstance().getValueByKey("custom-method.properties", "obj_" + tableObjName);
        if (Validator.isNull(attr)) {//判断是否动态表单
            ParamsVo vo = new ParamsVo();
            vo.setParams(map);
            attr = IusSqlTools.getInstance().densgerSql(vo, tableObjName);
        }
        String sysName = StrUtil.doNull(String.valueOf(map.get("datasource")), DynamicDataSource.getInstance().getDefaultDataSourceKey());
        String attrStr[] = attr.split(";");
        String tableName = attrStr[3];
        String atrrName = StringUtil.toCamelNamed(attrStr[2]);
        String infoId = String.valueOf(map.get(tableObjName+".w_"+atrrName));//主键与useIp值相等
        String cacheType = StrUtil.doNull(String.valueOf(map.get("cacheType")),"info");//
        String dataCacheKey = map.containsKey("dataCacheKey")?String.valueOf(map.get("dataCacheKey")):atrrName;
        String cache_spaceName = sysName+"_"+tableObjName+"_cache";
        String cacheWhere = String.valueOf(map.get("cacheWhere"));//查询条件
        if(modelTypes.startsWith("i_") || modelTypes.startsWith("u_")){
            if(StrUtil.isNull(infoId)) {
                Map<String, Object> resultIds = (Map) map.get("resultIds");
                if (resultIds != null) {
                    infoId = String.valueOf(resultIds.get(tableObjName+"_"+atrrName));
                }
            }
            buildCache(tableName, attrStr[2],infoId, cacheType, dataCacheKey, cache_spaceName,cacheWhere);
        } else if(modelTypes.startsWith("d_")){
            switch (cacheType) {
                case "list":
                    LoadCacheFactory.getInstance().getCacheManager(cache_spaceName).removeAll();
                    buildCache(tableName, attrStr[2],infoId, cacheType, dataCacheKey, cache_spaceName,cacheWhere);
                    break;
                case "info":
                default:
                    LoadCacheFactory.getInstance().getCacheManager(cache_spaceName).removeCacheObject(infoId);
            }
        }
        return null;
    }

    private void buildCache(final String tableName, final String cloumName,final String infoId, final String cacheType, final String dataCacheKey, final String cache_spaceName,final String cacheWhere) {
        ScheduledExecutor.instance().runable(new Runnable() {
            public void run() {
                try {
                    List<Map<String, String>> list;
                    switch (cacheType) {
                        case "list":
                            list = (List) IusPluginUtil.getInstance().select("select * from " + tableName + " where " + StrUtil.doNull(cacheWhere, "1=1").replace(" ", "="), 0, 0);
                            int count = list.size();
                            Map<String, List<Object>> maps = new HashMap();
                            for (int i = 0; i < count; i++) {
                                Map<String, String> obj = list.get(i);
                                List<Object> infos = maps.get(obj.get(dataCacheKey));
                                if (infos == null) {
                                    infos = new ArrayList();
                                }
                                infos.add(obj);
                                maps.put(obj.get(dataCacheKey), infos);
                            }
                            if (!maps.isEmpty()) {
                                for (Map.Entry<String, List<Object>> entry : maps.entrySet()) {
                                    LoadCacheFactory.getInstance().getCacheManager(cache_spaceName).createCacheObject(entry.getKey(), entry.getValue());
                                }
                            }
                            break;
                        case "info":
                        default:
                            list = (List) IusPluginUtil.getInstance().select("select * from " + tableName + " where " + cloumName + "='" + infoId + "'", 0, 0);
                            Map<String, String> info = list.get(0);
                            LoadCacheFactory.getInstance().getCacheManager(cache_spaceName).createCacheObject(info.get(dataCacheKey), info);
                    }
                }catch (Exception e){}
            }
        });
    }
}
